#include "cybertron/core/UtilStateHelper.hpp"
#include "cybertron/core/UtilPath.hpp"
#include "cybertron/core/UtilFile.hpp"
#include "cybertron/core/JsonReader.hpp"
#include "cybertron/core/Log.hpp"
CYBERTRON_BEGIN

UtilStateHelper::UtilStateHelper() {
}
UtilStateHelper::~UtilStateHelper() {

}

CybertronCoreAPI bool UtilStateHelper::InitWorkListCfg(string baseDir, string moduleCfgPath) {

	//logInfo("InitModuleCfg: basedir:%s,moduleCfgPath:%s", baseDir.c_str(), moduleCfgPath.c_str());
	if (!UtilFile::exist(moduleCfgPath))
	{
		logWarning("InitModuleCfg Config file %s doesn't exist.", moduleCfgPath.c_str());
		return false;
	}

	cybertron::json jsonNode;
	if (!JsonReader::loadFile(jsonNode, moduleCfgPath))
	{
		logError("json load  file error: %s", moduleCfgPath.c_str());
		return false;
	}


	string 	version = JsonReader::getString(jsonNode, "version");
	if (version != "2.0.0.0") {
		logError("module file version has problem  %s", version.c_str());
		return false;
	}

	auto moduleList = JsonReader::getChild(jsonNode, "moduleList");

	for (int i = 0; i < moduleList.size(); ++i)
	{
		auto& item = moduleList[i];
		string name = JsonReader::getString(item, "Name");
		string param = JsonReader::getString(item, "param");
		Common::EWorkNodeType type = (Common::EWorkNodeType)JsonReader::getInt(item, "Type");
		auto pathList = JsonReader::getChild(item, "Path");
		if (JsonReader::hasValue(item, "Attach")) {
			int attach = JsonReader::getInt(item, "Attach");
			if (attach != 0) {
				mWorkType2DebugAttachMap[type] = attach;
			}
			
		}
		
		mWorkNodeName2TypeMap[name] = type;
		mWorkType2NameMap[type] = name;
		
		if (param.size() > 0) {
			mWorkType2CommandLineMap[type] = param;
		}
		bool bFind = false;
		for (int j = 0; j < pathList.size(); ++j) {
			string path = JsonReader::getString(pathList[j]);

			string tmp = path + name;
			std::string nameFilePath = UtilPath::combine(baseDir, tmp);
#ifdef CYBERTRON_WIN
			bool exist = UtilFile::exist(nameFilePath + ".exe");
#else
			bool exist = UtilFile::exist(nameFilePath);
#endif
			if (!exist) {
				//logWarning("Can Not Find The Moudle Path[%s]", name.c_str());
				continue;
			}
			bFind = true;
			mWorkType2PathMap[type] = nameFilePath;
			//logInfo("The Moudle On Disk Path[%s] ===> %s ", name.c_str(), nameFilePath.c_str());
		}
		if (!bFind) {
			logError("The Moudle Can Not Finded On Disk[%s]", name.c_str());
		}
		
	}

	return true;
}

CybertronCoreAPI bool UtilStateHelper::InitNameTypeMap(string jsonContent) {
	cybertron::json jsonNode;
	if (!JsonReader::loadString(jsonNode, jsonContent))
	{
		logError("InitNameTypeMap loadString error");
		return false;
	}


	int code = JsonReader::getInt(jsonNode, "code");
	if (code != 0) {
		logError("InitNameTypeMap code:  %d", code);
		return false;
	}
	auto data = JsonReader::getChild(jsonNode, "data"); 
	std::string executablePath = UtilPath::getExecutablePath();
	for (auto it = data.begin(); it!= data.end(); it++)
	{
		string key = it.key();
		auto value = it.value();
		int type = JsonReader::getInt(value, "wokerType");
		Common::EWorkNodeType workType = (Common::EWorkNodeType)type;

		string path = JsonReader::getString(value, "path");

		mWorkNodeName2TypeMap[key] = workType;
		mWorkType2NameMap[workType] = key;
#ifdef CYBERTRON_WIN
		size_t pos = path.find_last_of(".");
		string moudePath = path.substr(0, pos);

		moudePath = UtilPath::combine(executablePath, moudePath);
		mWorkType2PathMap[workType] = moudePath;
#else	
		string moudePath = UtilPath::combine(executablePath, path);
		mWorkType2PathMap[workType] = moudePath;
#endif
	}
	return true;
}

CybertronCoreAPI bool UtilStateHelper::InitScalableTypeMap(string jsonContent) {
	cybertron::json jsonNode;
	if (!JsonReader::loadString(jsonNode, jsonContent))
	{
		logError("InitScalableTypeMap loadString error");
		return false;
	}
	int code = JsonReader::getInt(jsonNode, "code");
	if (code != 0) {
		logError("InitScalableTypeMap code:  %d", code);
		return false;
	}
	auto data = JsonReader::getChild(jsonNode, "data");
	for (auto it = data.begin(); it != data.end(); it++) {
		string key = it.key();
		Common::EWorkNodeType workType = Common::EWorkNodeType(atoi(key.c_str()));
		auto _list = it.value();
		WorkTypeList workList;
		for (int i = 0; i < _list.size(); ++i) {
			Common::EWorkNodeType type = _list[i];
			workList.push_back(type);
		}
		
		mScaleableNode2WorkTypeListMap[workType] = workList;
	}
	return true;
}
CybertronCoreAPI string UtilStateHelper::GetWorkNodeName(Common::EWorkNodeType workNodeType) {
	auto it = mWorkType2NameMap.find(workNodeType);
	if (it == mWorkType2NameMap.end()) {
		//logError("getWorkNodeName can not find type:%d", workNodeType);
		return "";
	}
	return it->second;
}
CybertronCoreAPI Common::EWorkNodeType UtilStateHelper::GetWorkNodeType(string workName) {
	auto it = mWorkNodeName2TypeMap.find(workName);
	if (it == mWorkNodeName2TypeMap.end()) {
		logError("Can not find name:%s", workName.c_str());
		return Common::EWorkNodeType_None;

	}
	return it->second;
}
CybertronCoreAPI string UtilStateHelper::GetWorkNodePath(Common::EWorkNodeType workNodeType) {
	auto it = mWorkType2PathMap.find(workNodeType);
	if (it == mWorkType2PathMap.end()) {
		//logError("Can not find type:%d[%s]", workNodeType, GetWorkNodeName(workNodeType).c_str());
		return "";

	}
	return it->second;
}
CybertronCoreAPI string UtilStateHelper::GetWorkNodeCommandLine(Common::EWorkNodeType workNodeType) {
	auto it = mWorkType2CommandLineMap.find(workNodeType);
	if (it == mWorkType2CommandLineMap.end()) {
		return "";
	}

	logInfo("getWorkNodeCommandLine  type:%d=====>%s:%s", workNodeType, GetWorkNodeName(workNodeType).c_str(), it->second.c_str());
	return it->second;
}
CybertronCoreAPI void UtilStateHelper::SetWorkNodeCfg(Common::EWorkNodeType workNodeType, string name, string path, string commandLine) {
	mWorkNodeName2TypeMap[name] = workNodeType;
	mWorkType2NameMap[workNodeType] = name;
#ifdef CYBERTRON_WIN
	bool exist = UtilFile::exist(path + ".exe");
#else
	bool exist = UtilFile::exist(path);
#endif
	if (exist) {
		logInfo("The Moudle path are finded on local disk[%s] ===> %s ", name.c_str(), path.c_str());
	}
	else {
		logWarning("Can Not Find The Moudle Path[%s]", name.c_str());
		return;
	}
	
	mWorkType2PathMap[workNodeType] = path;
	mWorkType2CommandLineMap[workNodeType] = commandLine;
	logInfo("SetWorkNodeCfg ====>work type:%d name:%s,commandline:%s, path:%s", workNodeType, name.c_str(), commandLine.c_str(), path.c_str());
	return;
}
CybertronCoreAPI bool UtilStateHelper::IsWorkNodeMayDebugAttach(Common::EWorkNodeType workNodeType) {
	auto it = mWorkType2DebugAttachMap.find(workNodeType);
	if (it != mWorkType2DebugAttachMap.end()) {
		return true;
	}
	return false;
}
CybertronCoreAPI bool  UtilStateHelper::GetScalableWorkNodeInfo(Common::EWorkNodeType workType, WorkTypeList& typeList) {
	auto it = mScaleableNode2WorkTypeListMap.find(workType);
	if (it != mScaleableNode2WorkTypeListMap.end()) {
		typeList = it->second;
		return true;
	}
	return false;
}
CybertronCoreAPI string UtilStateHelper::getWorkNodeStatusName(Common::EWorkNodeStatus workNodeStatus)
{
	string str = "unknow";
	switch (workNodeStatus)
	{
	case Common::EWorkNodeStatusNone:
		str = "WorkNodeStatusNone";
		break;
	case Common::EWorkNodeStatusFree:
		str = "WorkNodeStatusFree";
		break;
	case Common::EWorkNodeStatusPit:
		str = "WorkNodeStatusPit";
		break;
	case Common::EWorkNodeStatusWorking:
		str = "WorkNodeStatusWorking";
		break;
	case Common::EWorkNodeStatusLock:
		str = "WorkNodeStatusLock";
		break;
	default:
		break;
	}
	return str;
}

CybertronCoreAPI string UtilStateHelper::getWorkNodeStateName(Common::EWorkNodeState workNodeState)
{
	string str = "unknow";
	switch (workNodeState)
	{
	case Common::EWorkNodeStateNone:
		str = "WorkNodeStateNone";
		break;
	case Common::EWorkNodeStateFree:
		str = "WorkNodeStateFree";
		break;
	case Common::EWorkNodeStateStarting:
		str = "WorkNodeStateStarting";
		break;
	case Common::EWorkNodeStateStarted:
		str = "WorkNodeStateStarted";
		break;
	case Common::EWorkNodeStateInitFinish:
		str = "WorkNodeStateInitFinish";
		break;
	case Common::EWorkNodeStateRunning:
		str = "WorkNodeStateRunning";
		break;
	case Common::EWorkNodeStateEndingWork:
		str = "EWorkNodeStateEndingWork";
		break;
	case Common::EWorkNodeStateEndingTask:
		str = "EWorkNodeStateEndingTask";
		break;
	case Common::EWorkNodeStateWaitEnding:
		str = "EWorkNodeStateWaitEnding";
		break;
	case Common::EWorkNodeStateEnded:
		str = "WorkNodeStateEnded";
		break;
	default:
		break;
	}
	return str;
}

CybertronCoreAPI string UtilStateHelper::getTaskStateName(Common::ETaskState taskState)
{
	string str = "unknow";
	switch (taskState)
	{
	case Common::ETaskState_None:
		str = "TaskState_None";
		break;
	case Common::ETaskState_Ready:
		str = "ETaskState_Ready";
		break;
	case Common::ETaskState_Starting:
		str = "TaskState_Starting";
		break;
	case Common::ETaskState_Started:
		str = "TaskState_Started";
		break;
	case Common::ETaskState_Running:
		str = "TaskState_Running";
		break;
	case Common::ETaskState_Ending:
		str = "TaskState_Ending";
		break;
	case Common::ETaskState_Ended:
		str = "TaskState_Ended";
		break;
	default:
		break;
	}
	return str;
}

CybertronCoreAPI string UtilStateHelper::getWorkNodeTypeName(Common::EWorkNodeType workNodeType)
{
	string str = "unknow";
	switch (workNodeType)
	{
		case Common::EWorkNodeType_None:
			str = "EWorkNodeType_None";
			break;
		case Common::EWorkNodeType_CybertronNodeTimer:
			str = "CybertronNodeTimer";
			break;
		case Common::EWorkNodeType_CybertronTraffic:
			str = "CybertronTraffic";
			break;
		case Common::EWorkNodeType_CybertronBridgeIO:
			str = "CybertronBridgeIO";
			break;
		case Common::EWorkNodeType_CybertronVehicleDynamic:
			str = "VehicleDynamic";
			break;
		case Common::EWorkNodeType_CybertronVehicle:
			str = "CybertronVehicle";
			break;
		case Common::EWorkNodeType_CybertronTrafficProvider:
			str = "CybertronTrafficProvider";
			break;
		case Common::EWorkNodeType_CybertronBridgePerfectPlan:
			str = "CybertronBridgePerfectPlan";
			break;
		case Common::EWorkNodeType_CybertronBridgeSimOneDriver:
			str = "CybertronBridgeSimOneDriver";
			break;
		case Common::EWorkNodeType_CybertronUeCpuSensor:
			str = "CybertronUeCpuSensor";
			break;
		case Common::EWorkNodeType_CybertronBridgeLiDAR:
			str = "CybertronBridgeLiDAR";
			break;
		case Common::EWorkNodeType_CybertronPerfectSensor:
			str = "PerfectSensor";
			break;
		case Common::EWorkNodeType_CybertronBridgeCamera:
			str = "CybertronBridgeCamera";
			break;
		case Common::EWorkNodeType_CybertronBridgeRadar:
			str = "CybertronBridgeRadar";
			break;
		case Common::EWorkNodeType_CybertronBridgeUltrasonic:
			str = "CybertronBridgeUltrasonic";
			break;
		case Common::EWorkNodeType_CybertronBridgeFusion:
			str = "CybertronBridgeFusion";
			break;
		case Common::EWorkNodeType_CybertronBridgeV2X:
			str = "CybertronBridgeV2X";
			break;
		case Common::EWorkNodeType_CybertronSensor:
			str = "CybertronSensor";
			break;
		case Common::EWorkNodeType_CybertronUeGpuSensor:
			str = "CybertronUeGpuSensor";
			break;
		case Common::EWorkNodeType_CybertronJudge:
			str = "CybertronJudge";
			break;
		case Common::EWorkNodeType_CybertronJudgeConsole:
			str = "CybertronJudgeConsole";
			break;
		case Common::EWorkNodeType_CybertronVisualizer:
			str = "CybertronVisualizer";
			break;
		case Common::EWorkNodeType_CybertronObserver:
			str = "CybertronObserver";
			break;
		case Common::EWorkNodeType_CybertronVR:
			str = "CybertronVR";
			break;
		case Common::EWorkNodeType_CybertronBridgeAllspark:
			str = "CybertronBridgeAllspark";
			break;
		case Common::EWorkNodeType_CybertronMaster:
			str = "CybertronMaster";
			break;
		case Common::EWorkNodeType_CybertronAgent:
			str = "CybertronAgent";
			break;
		case Common::EWorkNodeType_CybertronBridgeApollo:
			str = "CybertronBridgeApollo";
			break;
	default:
			break;
	}
	return str;
}

CybertronCoreAPI  Common::EWorkNodeType UtilStateHelper::getWorkNodeTypeName(string strType) {
	Common::EWorkNodeType type = Common::EWorkNodeType_None;


	if (strType =="CybertronNodeTimer" ) {
		type = Common::EWorkNodeType_CybertronNodeTimer;
	}
	else 
		if (strType == "CybertronTraffic") {
		type = Common::EWorkNodeType_CybertronTraffic;
	}else
	if (strType == "CybertronBridgeIO") {
		type = Common::EWorkNodeType_CybertronBridgeIO;
	}else
	if (strType == "VehicleDynamic") {
		type = Common::EWorkNodeType_CybertronVehicleDynamic;
	}
	else
	if (strType == "CybertronMaster") {
		type = Common::EWorkNodeType_CybertronMaster;
	}
	else
		if (strType == "CybertronVehicle") {
			type = Common::EWorkNodeType_CybertronVehicle;
		}
	else
		if (strType == "CybertronTrafficProvider") {
			type = Common::EWorkNodeType_CybertronTrafficProvider;
		}
	else
		if (strType == "CybertronBridgePerfectPlan") {
			type = Common::EWorkNodeType_CybertronBridgePerfectPlan;
		}
	else
		if (strType == "CybertronBridgeSimOneDriver") {
			type = Common::EWorkNodeType_CybertronBridgeSimOneDriver;
		}
	else
		if (strType == "CybertronUeCpuSensor") {
			type = Common::EWorkNodeType_CybertronUeCpuSensor;
		}
	else
		if (strType == "CybertronBridgeLiDAR") {
			type = Common::EWorkNodeType_CybertronBridgeLiDAR;
		}
	else
	if (strType == "PerfectSensor") {
		type = Common::EWorkNodeType_CybertronPerfectSensor;
	}
	else
	if (strType == "CybertronBridgeCamera") {
		type = Common::EWorkNodeType_CybertronBridgeCamera;
	}
	else
	if (strType == "CybertronBridgeRadar") {
		type = Common::EWorkNodeType_CybertronBridgeRadar;
	}
	else
	if (strType == "CybertronBridgeUltrasonic") {
		type = Common::EWorkNodeType_CybertronBridgeUltrasonic;
	}
	else
	if (strType == "CybertronBridgeFusion") {
		type = Common::EWorkNodeType_CybertronBridgeFusion;
	}
	else
	if (strType == "CybertronBridgeUltrasonic") {
		type = Common::EWorkNodeType_CybertronBridgeUltrasonic;
	}
	else
	if (strType == "CybertronBridgeFusion") {
		type = Common::EWorkNodeType_CybertronBridgeFusion;
	}
	else
	if (strType == "CybertronBridgeV2X") {
		type = Common::EWorkNodeType_CybertronBridgeV2X;
	}
	else
	if (strType == "CybertronSensor") {
		type = Common::EWorkNodeType_CybertronSensor;
	}
	else
	if (strType == "CybertronUeGpuSensor") {
		type = Common::EWorkNodeType_CybertronUeGpuSensor;
	}
	else
	if (strType == "CybertronJudge") {
		type = Common::EWorkNodeType_CybertronJudge;
	}
	else
	if (strType == "CybertronJudgeConsole") {
		type = Common::EWorkNodeType_CybertronJudgeConsole;
	}
	else
	if (strType == "CybertronVisualizer") {
		type = Common::EWorkNodeType_CybertronVisualizer;
	}
	else
	if (strType == "CybertronObserver") {
		type = Common::EWorkNodeType_CybertronObserver;
	}
	else if (strType == "CybertronVR") {
		type = Common::EWorkNodeType_CybertronVR;
	}
	else if (strType == "CybertronBridgeAllspark") {
		type = Common::EWorkNodeType_CybertronBridgeAllspark;
	}
	else
	if (strType == "CybertronMaster") {
		type = Common::EWorkNodeType_CybertronMaster;
	}
	else
	if (strType == "CybertronAgent") {
		type = Common::EWorkNodeType_CybertronAgent;
	}
	else
	if (strType == "CybertronBridgeApollo") {
		type = Common::EWorkNodeType_CybertronBridgeApollo;
	}

	return type;
}
CybertronCoreAPI  string UtilStateHelper::getTaskRunnerPoolStateName(TaskRunnerPool::ETaskRunnerPoolState state) {
	string str = "unknow";
	switch (state)
	{
	case TaskRunnerPool::ETaskRunnerPoolStateReadying:
		str = "ETaskRunnerPoolStateReadying";
		break;
	case TaskRunnerPool::ETaskRunnerPoolStateFree:
		str = "ETaskRunnerPoolStateFree";
		break;
	case TaskRunnerPool::ETaskRunnerPoolStateLock:
		str = "ETaskRunnerPoolStateLock";
		break;
	case TaskRunnerPool::ETaskRunnerPoolStatePreDo:
		str = "ETaskRunnerPoolStatePreDo";
		break;
	case TaskRunnerPool::ETaskRunnerPoolStateDoing:
		str = "ETaskRunnerPoolStateDoing";
		break;
	case TaskRunnerPool::ETaskRunnerPoolStateDone:
		str = "ETaskRunnerPoolStateDone";
		break;

	default:
		break;
	}
	return str;
}
CYBERTRON_END
